package com.allwees.bs.c.module.order.mapper;

import com.allwees.bs.c.module.order.dto.OrderDTO;
import com.allwees.bs.c.module.order.entity.LogisticsWaybillEntity;
import com.allwees.bs.c.module.order.entity.OrderEntity;
import com.allwees.bs.c.module.order.entity.OrderFlowEntity;
import com.allwees.bs.c.module.order.entity.OrderItemEntity;
import com.allwees.bs.c.module.order.entity.OrderRefundEntity;
import com.allwees.bs.c.module.order.entity.OrderSkuSnapEntity;
import com.allwees.bs.c.module.order.repository.LogisticsWaybillEntityRepository;
import com.allwees.bs.c.module.order.repository.OrderFlowRepository;
import com.allwees.bs.c.module.order.repository.OrderItemRepository;
import com.allwees.bs.c.module.order.repository.OrderRepository;
import com.allwees.bs.c.module.order.repository.OrderSkuSnapRepository;
import com.allwees.bs.c.module.order.service.IOrderRefundService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

@Component
public class OrderMapper {
    @Autowired
    private IOrderRefundService orderRefundService;
    @Autowired
    private OrderRepository orderRepository;
    @Autowired
    private OrderItemRepository orderItemRepository;
    @Autowired
    private LogisticsWaybillEntityRepository orderLogisticsRepository;
    @Autowired
    private OrderSkuSnapRepository orderSkuSnapRepository;
    @Autowired
    private OrderFlowRepository orderFlowRepository;

//	public OrderDTO entity2DTO(OrderEntity entity) {
//		if(entity == null) {
//			return null;
//		}
//
//		OrderDTO order = new OrderDTO(entity);
//		return order;
//	}
//
//	public PaginateDTO<OrderDTO> entity2DTO(List<OrderEntity> entities, long total, PageParams pageParams) {
//		if(entities == null) {
//			return PaginateDTO.of(0, 0, pageParams);
//		}
//
//		PaginateDTO<OrderDTO> orderPaginateDTO = PaginateDTO.of(total, entities.size(), pageParams);
//		List<OrderDTO> orders = new ArrayList<>();
//		entities.forEach(entity -> orders.add(entity2DTO(entity)));
//
//		Set<String> orderUuids = orders.stream().map(OrderDTO::getUuid).collect(Collectors.toSet());
//		Map<String, OrderRefundEntity> refundMap = orderRefundService.getRefunds(orderUuids);
//
//		orders.forEach(o->{
//			o.getItems().forEach(item->{
//				OrderRefundEntity orderRefundEntity = refundMap.get(item.getUuid());
//				item.setRefundInfo(orderRefundEntity);
//			});
//		});
//
//		orderPaginateDTO.setResults(orders);
//		return orderPaginateDTO;
//	}

    public OrderDTO toDto(String orderUuid) {
        return toDto(orderRepository.getByUuid(orderUuid), true);
    }

    public OrderDTO toDto(OrderEntity order) {
        return toDto(order, true);
    }

    public OrderDTO toSimpleDto(OrderEntity order) {
        return toDto(order, false);
    }

    public OrderDTO toDto(OrderEntity order, boolean isFillLogistics) {
        if (order == null) {
            return null;
        }
        List<OrderItemEntity> orderItems = order.getOrderItems();
        if (null == orderItems) {
             orderItems = orderItemRepository.findOrderItems(order.getUuid());
        }

        List<LogisticsWaybillEntity> itemLogistics = new ArrayList<>();
        if (isFillLogistics) {
            itemLogistics = orderLogisticsRepository.findByOrderUuid(order.getUuid());
        }

        List<OrderFlowEntity> orderFlows = orderFlowRepository.getByOrderUuid(order.getUuid());
        List<OrderSkuSnapEntity> orderSkuSnaps = orderSkuSnapRepository.getByOrderUuid(order.getUuid());
        Map<String, OrderRefundEntity> refundMap = orderRefundService.getRefunds(new HashSet<>(Collections.singletonList(order.getUuid())));

        return new OrderDTO(order, orderFlows)
                .setOrderItems(orderItems, orderSkuSnaps, itemLogistics, refundMap);
    }

    public List<OrderDTO> toDtos(List<OrderEntity> orders) {
        if (CollectionUtils.isEmpty(orders)) {
            return new ArrayList<>();
        }

        Set<String> orderUuids = orders.stream().map(OrderEntity::getUuid).collect(Collectors.toSet());

        List<OrderSkuSnapEntity> orderSkuSnaps = orderSkuSnapRepository.findByOrderUuidIn(orderUuids);
        Map<String, List<OrderSkuSnapEntity>> orderSkuSnapMap = orderSkuSnaps.stream().collect(Collectors.groupingBy(OrderSkuSnapEntity::getOrderUuid));

        List<OrderItemEntity> orderItems = orderItemRepository.findByOrderUuidIn(orderUuids);
        Map<String, List<OrderItemEntity>> orderItemMap = orderItems.stream().collect(Collectors.groupingBy(OrderItemEntity::getOrderUuid));

        List<OrderDTO> dtos = new ArrayList<>(orders.size());

        for (OrderEntity order : orders) {
            List<LogisticsWaybillEntity> itemLogistics = orderLogisticsRepository.findByOrderUuid(order.getUuid());
            OrderDTO dto = new OrderDTO(order, new ArrayList<>(0))
                    .setOrderItems(orderItemMap.get(order.getUuid()), orderSkuSnapMap.get(order.getUuid()), itemLogistics, new HashMap<>(0));
            dtos.add(dto);
        }
        return dtos;
    }
}
